package midi;

import java.util.ArrayList;
import java.util.List;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.sound.midi.Transmitter;
import javax.sound.midi.MidiDevice.Info;


public class MidiController implements Runnable{
	private Sequencer sequencer;
	private List<MidiPhrase> queuedPhrase;
	private Sequence currSequence;
	private Track prevTrack;
	private boolean run = false;
	private float queuedBPM;
	private long sleepTime;

	public MidiController(){
		queuedPhrase = new ArrayList<MidiPhrase>();
		try{
			sequencer = MidiSystem.getSequencer();
			sequencer.open();
			sequencer.setTempoFactor(1);
			currSequence = new Sequence(Sequence.PPQ, 8);
			queuedBPM = sequencer.getTempoInBPM();
		}
		catch (Exception e){
			e.printStackTrace();
		}
	}

	public void setPhrase(MidiPhrase phrase){
		this.queuedPhrase.clear();
		this.queuedPhrase.add(phrase);
		run = true;
	}
	
	public void setPhrases(List<MidiPhrase> phrases){
		this.queuedPhrase.clear();
		for (int i = 0; i < phrases.size(); i++){
			this.queuedPhrase.add(phrases.get(i));
		}
	}
	
	public void setBPM(float bpm){
		queuedBPM = bpm;
	}

	public void start(){
		run = true;
	}

	public void stop(){
		run = false;
	}

	@Override
	public void run() {
		while (1 == 1){
			if (run){
				sequencer.setTempoInBPM(queuedBPM);
				sleepTime = (long) (60000 / queuedBPM * 12 / 4);
				System.out.println(sleepTime);
				if (sleepTime > 4000){
					sleepTime = 4000;
				}
				
				currSequence.deleteTrack(prevTrack);
				prevTrack = currSequence.createTrack();

				for (int i = 0; i < queuedPhrase.size(); i++){
					queuedPhrase.get(i).addToTrack(prevTrack, 0, 0);
				}

				try {
					sequencer.setSequence(currSequence);
					sequencer.setTickPosition(0);
					sequencer.start();

					
					Thread.sleep(3000);

					sequencer.stop();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			else
			{
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}
}
